package net.sansi.v3correctserver.task;

import cn.hutool.extra.spring.SpringUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import net.sansi.v3correctserver.constenum.AppHelper;
import net.sansi.v3correctserver.dto.correctresult.CorrectResultDto;
import net.sansi.v3correctserver.dto.v3serverapi.V3ServerCorrectDto;
import net.sansi.v3correctserver.entity.screen.ScanBoard;
import net.sansi.v3correctserver.entity.space.CorrectCnf;
import net.sansi.v3correctserver.exception.ServiceException;
import net.sansi.v3correctserver.service.space.ProjectSpace;
import net.sansi.v3correctserver.service.v3serverapi.V3ServerCorrectApi;
import net.sansi.v3correctserver.util.CmmUtil;

import java.util.List;

public class SolidifyFactorTask extends V3Task<SolidifyFactorTask,
        SolidifyFactorTask.Progress> {

    private CorrectResultDto.StartSolidifyFactorReq params;
    private List<ScanBoard> scanBoards;
    private ProjectSpace projectSpace;
    private CorrectCnf correctCnf;
    private V3ServerCorrectApi v3ServerCorrectApi;

    public SolidifyFactorTask(CorrectResultDto.StartSolidifyFactorReq params, List<ScanBoard> scanBoards) {
        super(5, new Progress());
        this.params = params;
        this.scanBoards = scanBoards;
        projectSpace = AppHelper.projectSpace();
        correctCnf = projectSpace.getCorrectCnf();
        v3ServerCorrectApi = SpringUtil.getBean(V3ServerCorrectApi.class);
    }

    @Override
    void runHandler() throws Exception {
        mock();
    }

    /**
     * 模拟系数固化
     */
    private void mock() {
        for (int i = 0; i <= 100; i++) {
            CmmUtil.sleep(200);
            progress.setProgress((double) i);
        }
    }

    private void solidify() {
        V3ServerCorrectDto.StartSolidifyFactorReq req = new V3ServerCorrectDto.StartSolidifyFactorReq();
        req.setAction(params.getAction());
        req.setDataType(params.getDataType());

        for (ScanBoard scanBoard : scanBoards) {
            V3ServerCorrectDto.StartSolidifyFactorReq.Scanner scanner = new V3ServerCorrectDto.StartSolidifyFactorReq.Scanner();
            scanner.setId(scanBoard.getId());
            scanner.setName(scanBoard.getName());
            scanner.setType(scanBoard.getType());
            req.getScannerArr().add(scanner);
        }

        v3ServerCorrectApi.solidifyStart(correctCnf.getScreenId(), req);
        refreshProgress(() -> v3ServerCorrectApi.getSolidifyProgress(correctCnf.getScreenId()));
    }

    interface GetProgress {
        V3ServerCorrectDto.SolidifyProgressResp get();
    }

    /**
     * 刷新进度
     *
     * @param getProgress 获取进度的方法
     */
    private void refreshProgress(GetProgress getProgress) {
        long start = System.currentTimeMillis();

        while (true) {
            V3ServerCorrectDto.SolidifyProgressResp resp = getProgress.get();
            progress.setProgress(Double.valueOf(resp.getScreenProgress().getProgress()));
            progress.solidifyStatus = resp.getScreenProgress().getStatus();
            if (resp.getScreenProgress().getStatus().equals("success")) break;
            CmmUtil.sleep(1000);
            if (System.currentTimeMillis() - start > 1000 * 60 * 5) {
                throw new ServiceException("固化超时");
            }
        }
    }

    @Getter
    @Setter
    @ApiModel("固化系数进度")
    public static class Progress extends V3Task.Progress {

        @ApiModelProperty("进度")
        private Double progress = 0d;

        @ApiModelProperty("状态")
        private String solidifyStatus = "";
    }
}
